package com.zerui.manager.app.deviceTouchSync.job;

import com.alibaba.fastjson.JSONObject;
import com.dahuatech.icc.exception.ClientException;
import com.zerui.cola.dto.PageResponse;
import com.zerui.devicemanager.provider.DeviceDubboService;
import com.zerui.devicemanager.provider.cmd.DeviceNodePageCmd;
import com.zerui.devicemanager.provider.dto.DeviceDTO;
import com.zerui.manager.app.deviceTouch.executer.DeviceTouchQryCmdExe;
import com.zerui.manager.app.deviceTouchSync.executer.DeviceTouchSyncQryCmdExe;
import com.zerui.manager.app.deviceTouchSync.executer.DeviceTouchSyncUpdateCmdExe;
import com.zerui.manager.app.scheduler.bean.JobConst;
import com.zerui.manager.app.scheduler.utils.ScheduleUtils;
import com.zerui.manager.common.util.ExceptionUtils;
import com.zerui.manager.deviceTouch.DeviceTouch;
import com.zerui.manager.deviceTouch.domainservice.DeviceTouchRepository;
import com.zerui.manager.deviceTouchSync.DeviceTouchSync;
import com.zerui.manager.icc.conf.ICCDictFileConf;
import com.zerui.manager.icc.service.DeviceInfoService;
import com.zerui.manager.iot.conf.IOTDictRemoteConf;
import com.zerui.manager.web.enums.AuthTaskSyncStatusEnum;
import com.zerui.manager.web.enums.DeviceFromEnum;
import com.zerui.manager.web.vo.icc.DeviceInfoVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

@Slf4j
@Component("deviceSyncJob")
public class DeviceSyncJob {
    @Value("${spring.application.name}")
    private String applicationName;
    @Resource
    private Scheduler scheduler;
    @Resource
    private DeviceTouchQryCmdExe deviceTouchQryCmdExe;
    @Resource
    private DeviceTouchSyncQryCmdExe deviceTouchSyncQryCmdExe;
    @Resource
    private DeviceTouchSyncUpdateCmdExe deviceTouchSyncUpdateCmdExe;
    @Resource
    private DeviceTouchRepository deviceTouchRepository;
    @DubboReference
    private DeviceDubboService deviceDubboService;
    @Resource
    private DeviceInfoService deviceInfoService;
    @Resource
    private ICCDictFileConf iccDictFileConf;
    @Resource
    private IOTDictRemoteConf iotDictRemoteConf;

    public void run(String id) {
        DeviceTouchSync touchSync = null;
        try {
            touchSync = deviceTouchSyncQryCmdExe.selectById(Long.parseLong(id));
            if (null == touchSync || touchSync.getSyncStatus() == AuthTaskSyncStatusEnum.SYNC_DOING.getCode()) {
                System.out.println("任务->" + JSONObject.toJSONString(touchSync));
                return;
            }
            deviceTouchSyncUpdateCmdExe.syncStatus(Long.parseLong(id), AuthTaskSyncStatusEnum.SYNC_DOING, LocalDateTime.now());
            if (touchSync.getSyncFrom() == DeviceFromEnum.FROM_IOT.getCode()) {
                deviceTouchRepository.handSyncTouchDevices(this.touchIoTDevices(), touchSync);
            } else if (touchSync.getSyncFrom() == DeviceFromEnum.FROM_ICC.getCode()) {
                deviceTouchRepository.handSyncTouchDevices(this.touchICCDevices(), touchSync);
            }
            // 同步数据
            touchSync.setSyncStatus(AuthTaskSyncStatusEnum.SYNC_DONE.getCode());
            deviceTouchSyncUpdateCmdExe.updateSyncInfo(touchSync);
        } catch (Exception e) {
            touchSync.setSyncStatus(AuthTaskSyncStatusEnum.SYNC_FAILURE.getCode());
            touchSync.setSyncRemark(ExceptionUtils.getRootErrorMessage(e));
            deviceTouchSyncUpdateCmdExe.updateSyncInfo(touchSync);
            log.error("执行任务出错", e);
        } finally {
            try {
                ScheduleUtils.deleteJob(scheduler, Long.parseLong(id), JobConst.GROUP_DEVICE_TOUCH);
            } catch (SchedulerException e) {
                log.error("删除该任务出错", e);
            }
        }
    }

    // 落地IoT门禁设备
    private List<DeviceTouch> touchIoTDevices() {
        int page = 1, pageSize = 100, totalCount = 0;
        List<DeviceTouch> touchDevices = new ArrayList<>();
        DeviceNodePageCmd nodePageCmd = new DeviceNodePageCmd();
        nodePageCmd.setBizUnit(applicationName);
        nodePageCmd.setPageSize(pageSize);
        do {
            nodePageCmd.setPageIndex(page);
            PageResponse<DeviceDTO> pageResponse = deviceDubboService.getPageDevcieList(nodePageCmd);
            totalCount = pageResponse.getTotalCount();
            for (DeviceDTO dto : pageResponse.getData()) {
                touchDevices.add(DeviceTouch.ofIoTDevice(dto));
            }
            page++;
        } while ((page - 1) * pageSize < totalCount);
        return touchDevices;
    }

    private List<DeviceTouch> touchICCDevices() throws ClientException {
        List<DeviceTouch> touchDevices = new ArrayList<>();
        List<DeviceInfoVO> all = deviceInfoService.getAccessControls();
        for (DeviceInfoVO item : all) {
            DeviceTouch deviceTouch = DeviceTouch.ofIccDevice(item);
            deviceTouch.setDeviceManufacturer(iccDictFileConf.getManufacturerName(deviceTouch.getDeviceManufacturer()));
            deviceTouch.setProductName(iotDictRemoteConf.getProductName(deviceTouch.getProductCode()));
            touchDevices.add(deviceTouch);
        }
        return touchDevices;
    }
}
